/*
 * Encog(tm) Examples v2.4
 * http://www.heatonresearch.com/encog/
 * http://code.google.com/p/encog-java/
 * 
 * Copyright 2008-2010 by Heaton Research Inc.
 * 
 * Released under the LGPL.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 * 
 * Encog and Heaton Research are Trademarks of Heaton Research, Inc.
 * For information on Heaton Research trademarks, visit:
 * 
 * http://www.heatonresearch.com/copyright.html
 */

package mtamarket;

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import org.encog.ml.data.MLData;
import org.encog.ml.data.MLDataPair;
import org.encog.ml.data.market.MarketDataDescription;
import org.encog.ml.data.market.MarketDataType;
import org.encog.ml.data.market.MarketMLDataSet;
import org.encog.ml.data.market.loader.MarketLoader;
import org.encog.ml.data.market.loader.YahooFinanceLoader;
import org.encog.ml.data.temporal.TemporalMLDataSet;
import org.encog.neural.data.NeuralData;
import org.encog.neural.networks.BasicNetwork;
import org.encog.persist.EncogDirectoryPersistence;

public class MarketEvaluate {

	enum Direction {
		up, down
	};

	public static Direction determineDirection(double d) {
		if (d < 0)
			return Direction.down;
		else
			return Direction.up;
	}

	public static void evaluate(File dataDir, Config config, String fileName) {

		File file = new File(dataDir,fileName);

		if (!file.exists()) {
			System.out.println("Can't read file: " + file.getAbsolutePath());
			return;
		}
		
		BasicNetwork network = null;

		if(fileName.endsWith(".eg")){
			network = (BasicNetwork)EncogDirectoryPersistence.loadObject(file);
		}else{
			network = BobsUtility.getNetwork(fileName);
		}
		
		DecimalFormat format = new DecimalFormat("#0.00");
		
		int count = 0;
		int correct = 0;
		
		double[][] transformedData = config.transformedData;
		
		
		
		double[] output = new double[Config.numberOfForecasts];
		
		int startEval = transformedData.length - Config.numberOfForecasts;
		
		double[] inputData;
		
		double[] actuals = new double[Config.numberOfForecasts];
		double[] pcactuals = new double[Config.numberOfForecasts];
		
		double lastActual = config.rawData[config.rawData.length - Config.numberOfForecasts][0]; 
		
		double[] rawPredictions = new double[Config.numberOfForecasts];
		
		double mape = 0;
		
		//actuals is last "numberOfForecasts" actual values of first column
		for(int i = 0; i < Config.numberOfForecasts; i++){
			actuals[i] = config.rawData[config.rawData.length - Config.numberOfForecasts + i][0];
			pcactuals[i] = transformedData[transformedData.length - Config.numberOfForecasts + i][0];
		}
		
		inputData = transformedData[transformedData.length - Config.numberOfForecasts - 1];
		
		network.compute(inputData, output);
		
		for(int i = 0; i < Config.numberOfForecasts; i++){
			rawPredictions[i] = lastActual * (1 + output[i]);
			lastActual = rawPredictions[i];
		}
		
		System.out.println("\nPercent Change:");
		
		System.out.println("Actual    Prediction");
		
		for(int i = 0; i < Config.numberOfForecasts; i++){
			System.out.println(pcactuals[i] + " | " + output[i]);
			if(determineDirection(pcactuals[i]).equals(determineDirection(output[i]))){
				correct++;
			}
		}
		
		System.out.println("\nRaw:");
		
		System.out.println("Actual    Prediction");
		
		for(int i = 0; i < Config.numberOfForecasts; i++){
			System.out.println(actuals[i] + " | " + rawPredictions[i]);
			mape += (Math.abs((actuals[i] - rawPredictions[i]) / actuals[i]));
		}
		
		count = Config.numberOfForecasts;
		
		
		
		double percent = (double) correct / (double) count;
		System.out.println("Direction correct:" + correct + "/" + count);
		System.out.println("Directional Accuracy:"
				+ format.format(percent * 100) + "%");

		System.out.println("Mape: " + format.format(mape * 100 /count) + "%");
	}

}
